package com.dbz.util;


import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
public class JWTFilter extends BasicHttpAuthenticationFilter{
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 登录标识
     */
    private static String LOGIN_SIGN = "Authorization";
    /**
     * 如果带有 token，则对 token 进行检查，否则直接通过
     * 拦截器
     */
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws UnauthorizedException {
        //判断请求的请求头是否带上 "token"
       if (isLoginAttempt(request, response)) {
            //如果存在，则进入 executeLogin 方法执行登入，检查 token 是否正确
            try {
                 executeLogin(request, response);
                 return true;
            } catch (Exception e) {
                //token 错误
               throw new AuthorizationException("权限不足",e);
            }
       }
        //如果请求头不存在 token，则可能是执行登陆操作或者是游客状态访问，无需检查 token，直接返回 true
        throw new NotokenException("沒有携带Token");
    }

    /**
     * 判断用户是否想要登入。
     * 检测 header 里面是否包含 token 字段
     */
    @Override
    protected boolean isLoginAttempt(ServletRequest request, ServletResponse response) {
        HttpServletRequest req = (HttpServletRequest) request;
        String token = req.getParameter("token");
        return token != null;
    }

    /**
     * 执行登陆操作
     */
    @Override
    protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String token = httpServletRequest.getParameter("token");
        System.out.println(token+"？？？？？？？？？？？？？？执行登陆操作的token");
        JwtToken jwtToken = new JwtToken(token);
        System.out.println(jwtToken+">>>>>>>>jwtToken>>>>>>>>>>>>>>>>>>>");
        // 提交给realm进行登入，如果错误它会抛出异常并被捕获
        getSubject(request, response).login(jwtToken);
        System.out.println(">>>>>>>>jwtToken>>>>>>>>>>>>>>>>>>>");
        // 如果没有抛出异常则代表登入成功，返回true
        return true;
    }


    /**
     * 将非法请求跳转到 /unauthorized/**
     */
    private void responseError(ServletResponse response, String message) {
        try {
            HttpServletResponse httpServletResponse = (HttpServletResponse) response;
            //设置编码，否则中文字符在重定向时会变为空字符串
            message = URLEncoder.encode(message, "UTF-8");
            httpServletResponse.sendRedirect("/unauthorized/" + message);
        } catch (IOException e) {
            logger.error(e.getMessage());
        }
    }
}
